package com.heima.comment.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.comment.service.CommentHotService;
import com.heima.comment.service.CommentService;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.feigns.admin.AdminFeign;
import com.heima.feigns.user.UserFeign;
import com.heima.model.comment.dtos.CommentDto;
import com.heima.model.comment.dtos.CommentLikeDto;
import com.heima.model.comment.dtos.CommentSaveDto;
import com.heima.comment.pojos.ApComment;
import com.heima.comment.pojos.ApCommentLike;
import com.heima.comment.vos.ApCommentVo;
import com.heima.model.common.constants.HotArticleConstants;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.mess.app.UpdateArticleMess;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.utils.threadlocal.AppThreadLocalUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class CommentServiceImpl implements CommentService{
    @Autowired
    MongoTemplate mongoTemplate;
    @Autowired
    private UserFeign userFeign;
    @Autowired
    CommentHotService commentHotService;
    //内容审核用
    @Autowired
    AdminFeign adminFeign;
    @Autowired
    GreenTextScan textScan;

    @Autowired
    KafkaTemplate kafkaTemplate;

    /**
     * 根据文章id查询评论列表 分页
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult findByArticleId(CommentDto dto) {
        //边界条件  ，此功能无需登录,加载页数要合理,登录时加载用户点赞列表
        if (dto==null || dto.getArticleId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        Integer size = dto.getSize();
        if (size==null||size<=0 || size>8){
            dto.setSize(8);
            size=8;
        }
        //查询评论当页列表***********************************需根据是否是首页查询热点评论********************
        List<ApComment> apComments=null;
        //评论首页
        if (dto.getIndex()==1){
            List<ApComment> commentHots = mongoTemplate.find(
                    Query.query(
                            Criteria.where("entryId").is(dto.getArticleId())
                                    .and("flag").is(1)
                    ).with(Sort.by(Sort.Direction.DESC, "likes")),
                    ApComment.class);
            //存在热评**************可以优化，if,else合并
            if (commentHots!=null &&commentHots.size()>0){
                size=size-commentHots.size();
                List<ApComment> commentNotHots = mongoTemplate.find(
                        Query.query(
                                Criteria.where("entryId").is(dto.getArticleId())
                                 .and("createdTime").lt(dto.getMinDate())
                                .and("flag").is(0)
                        ).limit(size).with(Sort.by(Sort.Direction.DESC, "createdTime"))
                        , ApComment.class
                );
                commentHots.addAll(commentNotHots);
                apComments=commentHots;
            }else {//没有热评
                apComments = mongoTemplate.find(
                        Query.query(
                                Criteria.where("entryId").is(dto.getArticleId())
                                        .and("createdTime").lt(dto.getMinDate())
                                        .and("flag").is(0)
                        ).limit(dto.getSize())
                                .with(Sort.by(Sort.Direction.DESC, "createdTime"))
                        , ApComment.class
                );
            }
        }else{
            //非首页
            apComments = mongoTemplate.find(
                    Query.query(
                            Criteria.where("entryId").is(dto.getArticleId())
                                    .and("createdTime").lt(dto.getMinDate())
                                    .and("flag").is(0)
                    ).limit(dto.getSize())
                            .with(Sort.by(Sort.Direction.DESC, "createdTime"))
                    , ApComment.class
            );
        }


        ApUser user = AppThreadLocalUtils.getUser();
        //未登录时直接返回结果
        if (user==null||user.getId()==null){
            return ResponseResult.okResult(apComments);
        }
        //登录时查询点赞列表
        List<ApCommentVo> apCommentVoList = new ArrayList<>();
        List<String> commentIds = apComments.stream().map(comment -> comment.getId()).collect(Collectors.toList());
        List<ApCommentLike> commentLikes = mongoTemplate.find(
                Query.query(
                        Criteria.where("commentId").in(commentIds)
                                .and("authorId").is(user.getId())
                )
                , ApCommentLike.class
        );
        //评论列表有当前用户点赞时回显数数据
        if (apComments!=null && apComments.size()>0 && commentLikes!=null && commentLikes.size()>0){
            apComments.forEach(apComment -> {
                ApCommentVo apCommentVo = new ApCommentVo();
                BeanUtils.copyProperties(apComment,apCommentVo);
                commentLikes.forEach(apCommentLike -> {
                    if (apComment.getId().equals(apCommentLike.getCommentId())){
                        apCommentVo.setOperation((short) 0);
                    }
                });
                apCommentVoList.add(apCommentVo);
            });
            return ResponseResult.okResult(apCommentVoList);
        }
        //否则直接返回评论列表
        return ResponseResult.okResult(apComments);
    }
    /**
     * 点赞评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(CommentLikeDto dto) {
        //边界条件校验
        if(dto==null ||dto.getCommentId()==null ||dto.getOperation()==null
        || dto.getOperation()<0 ||dto.getOperation()>1){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //需登录操作
        ApUser user = AppThreadLocalUtils.getUser();
        if (user==null||user.getId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //先查找再更新
        ApComment comment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        if (comment==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        /*
        * 0点赞操作 1取消点赞操作  判断不能重复操作,先查询
        * */
        ApCommentLike apCommentLike = mongoTemplate.findOne(
                Query.query(Criteria.where("authorId").is(user.getId())
                        .and("commentId").is(dto.getCommentId())),
                ApCommentLike.class
        );

        Map<String, Object> resultMap = new HashMap<>();//结果map,响应当前评论点赞数给前端
        if (dto.getOperation().intValue()==0){
            if (apCommentLike!=null){
                return ResponseResult.errorResult(AppHttpCodeEnum.DATA_EXIST,"不能重复点赞");
            }
            //点赞操作，评论表like+1,点赞表保存数据
            comment.setLikes(comment.getLikes()+1);
            mongoTemplate.save(comment);//评论点赞数+1
            //****************计算是否是热点，当点赞数超过5时需要判断************************************
            if (comment.getFlag().shortValue() == 0 && comment.getLikes() > 5) {
                commentHotService.hotCommentExecutor(comment.getEntryId(), comment);
            }
            apCommentLike=ApCommentLike.builder()
                    .authorId(user.getId())
                    .commentId(comment.getId())
                    .operation(dto.getOperation())
                    .build();
            mongoTemplate.save(apCommentLike);//保存点赞信息
            resultMap.put("likes",comment.getLikes());
            return ResponseResult.okResult(resultMap);
        }
        if (apCommentLike==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"无点赞信息");
        }
        //取消点赞操作，评论表like-1,点赞表修改数据
        comment.setLikes(comment.getLikes()<=0?0:(comment.getLikes()-1));
        mongoTemplate.save(comment);//评论点赞数-1
        mongoTemplate.remove(
                Query.query(Criteria.where("authorId").is(user.getId())
                        .and("commentId").is(dto.getCommentId()))
                ,ApCommentLike.class);//移除点赞信息
        resultMap.put("likes",comment.getLikes());
        return ResponseResult.okResult(resultMap);
    }

    /**
     * 保存评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveComment(CommentSaveDto dto) {
        //边界条件
        if (dto.getArticleId()==null ||dto.getContent()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        if (dto.getContent()!=null && dto.getContent().length()>140){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"评论不能超过140字");
        }
        ApUser user = AppThreadLocalUtils.getUser();
        if (user==null || user.getId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        ApUser apUser = userFeign.findUserById(user.getId());
        if (apUser==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"登录信息有误");
        }
        //文字内容审核---阿里组件，自定义敏感词
        boolean isSensitiveScan = handleSensitive(dto.getContent());
        if (!isSensitiveScan){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"评论不符合社会主义核心价值观");
        }
        /*boolean isTextScan = handleTextScan(dto.getContent());
        if (!isTextScan){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"评论不符合社会主义核心价值观");
        }*/

        //**** *************发表评论-发送消息给实时计算
        UpdateArticleMess mess = new UpdateArticleMess();
        mess.setAdd(1);
        mess.setType(UpdateArticleMess.UpdateArticleType.COMMENT);
        mess.setArticleId(dto.getArticleId());
        kafkaTemplate.send(HotArticleConstants.HOT_ARTICLE_SCORE_TOPIC,
                UUID.randomUUID().toString(), JSON.toJSONString(mess));
        // ************************

        //保存数据到mongodb
        ApComment comment = ApComment.builder()
                .authorId(apUser.getId())
                .authorName(apUser.getName())
                .image(apUser.getImage())
                .content(dto.getContent())
                .entryId(dto.getArticleId())
                .createdTime(new Date())
                .updatedTime(new Date())
                .likes(0)
                .reply(0)
                .type((short) 0)
                .flag((short) 0)
                .build();
        mongoTemplate.insert(comment);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 自管理敏感词审核
     * @param content
     * @return
     */
    private boolean handleSensitive(String content) {
        boolean flag = true;
        List<String> sensitives = adminFeign.findAllSensitive();

        SensitiveWordUtil.initMap(sensitives);
        Map<String, Integer> map = SensitiveWordUtil.matchWords(content);
        if (map.size()>0){
            flag=false;
        }
        return flag;
    }

    /**
     * 阿里云文字审核
     * @param content
     * @return
     */
    private boolean handleTextScan(String content){
        boolean flag=true;
        try {
            Map map = textScan.greeTextScan(content);
            if (map.get("suggestion").equals("block")||map.get("suggestion").equals("review")){
                flag=false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }
}